﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Xml.Serialization;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.VersionControl.Common;

namespace MergeTool.ClassLib.Configuration
{
    public enum DefaultWorkItemAssociation
    {
        Always,
        Never,
        OnlyWhenNoWorkItemAssociated
    }

    public class Settings
    {

        private static readonly string ConfigFilePath = Directory.GetCurrentDirectory() + @"\MergeTool.config";
        
        private static Settings _instance;

        private Settings() { }

        public static void Save()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Settings));
            StreamWriter streamWriter = new StreamWriter(ConfigFilePath);
            serializer.Serialize(streamWriter.BaseStream, _instance);
        }

        //private static Settings GetDefaultSettings()
        //{
        //    return new Settings()
        //    {
        //        IsMergeByChangesets = false,
        //        IsTransferCommentsBetweenChangesets = false,
        //        DefaultWorkItemToAssociate = 4,
        //        ConnectionInfo = new ConnectionInfo()
        //        {
        //            UserName = "petakaras@seznam.cz",
        //            TFSUriString = "https://tfsdestiny.visualstudio.com",
        //            ProjectCollection = "DefaultCollection",
        //            TeamProject = "MergingAndBranching"
        //        },
        //        MergeApproaches = new ObservableCollection<MergeApproach>()
        //            {
        //                new MergeApproach
        //                {
        //                    Name = "ExampleApproach",
        //                    Branches = new ObservableCollection<BranchPair>()
        //                    {
        //                        new BranchPair
        //                        {
        //                            BranchName = "r1.5.2",
        //                            Order = 1,
        //                            MergeOptionString = "None"
        //                        },  
        //                        new BranchPair
        //                        {
        //                            BranchName = "r1.5.2-tbranch",
        //                            Order = 2,
        //                            MergeOptionString = "Conservative"
        //                        },     
        //                        new BranchPair
        //                        {
        //                            BranchName = "DEV1",
        //                            Order = 3,
        //                            MergeOptionString = "Conservative"
        //                        },
        //                        new BranchPair
        //                        {
        //                            BranchName = "DEV2",
        //                            Order = 4,
        //                            MergeOptionString = "None"
        //                        },
        //                        new BranchPair
        //                        {
        //                            BranchName = "DEV1",
        //                            Order = 5,
        //                            MergeOptionString = "Conservative"
        //                        },
        //                        new BranchPair
        //                        {
        //                            BranchName = "DoesNotExist",
        //                            Order = 6
        //                        }
        //                    }
        //                },

        //                new MergeApproach
        //                {
        //                    Name = "ExampleApproach2",
        //                    Branches = new ObservableCollection<BranchPair>()
        //                    {
        //                        new BranchPair
        //                        {
        //                            BranchName = "r1.5.2",
        //                            Order = 1,
        //                            MergeOptionString = "None"
        //                        },  
        //                        new BranchPair
        //                        {
        //                            BranchName = "r1.5.2-tbranch",
        //                            Order = 2,
        //                            MergeOptionString = "Conservative"
        //                        },
        //                        new BranchPair
        //                        {
        //                            BranchName = "DEV2",
        //                            Order = 3,
        //                            MergeOptionString = "None"
        //                        },
        //                        new BranchPair
        //                        {
        //                            BranchName = "r1.5.2",
        //                            Order = 4,
        //                            MergeOptionString = "None"
        //                        }/*,
        //                        new Branch
        //                        {
        //                            BranchName = "DoesNotExist",
        //                            Order = 4
        //                        }*/
        //                    }
        //                }
        //            }
        //    };
        //}

        private static Settings Load()
        {
            if (File.Exists(ConfigFilePath))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Settings));
                FileStream configFile = new FileStream(ConfigFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                return (Settings)serializer.Deserialize(configFile);
            }
           
            return null;
        }

        public static Settings GetInstance()
        {
            if (_instance == null)
                _instance = Load();

            //if (_instance == null)
              //  _instance = GetDefaultSettings();

            return _instance;
        }
        
        public ConnectionInfo ConnectionInfo { get; set; }

        public bool IsMergeByChangesets { get; set; }

        public int DefaultWorkItemToAssociate { get; set; }

        public string TempWorkspacePath { get; set; }

        public bool MergeLoggedUserChangesets { get; set; }

        public bool BranchNameOnlyInComments { get; set; }

        public string DefaultBranchCheckinCommentPattern { get; set; }

        public string DefaultChangesetCheckinCommentPattern { get; set; }

        public bool IsKeepOriginalOwnerOfMergedChangeset { get; set; }

        public bool IsKeepMergeHistoryInComments { get; set; }

        public bool IsAlwaysShowCheckinConfirmation { get; set; }

        //CAB specific configuration part BEGIN
        public bool IsUsingCabFeatures { get; set; }

        public bool IsAutomaticVersionIncrease { get; set; }

        public string SpecialVersioningBranch { get; set; }

        public DefaultWorkItemAssociation DefaultWorkItemAssociation { get; set; }

        public string BeyondComparePath { get; set; }
        //CAB specific configuration part END

        public ObservableCollection<MergeApproach> MergeApproaches;

    }

    public class ConnectionInfo
    {
        [XmlIgnore]
        public Uri TFSUri{get; private set;}
        public string ProjectCollection { get; set; }
        public string TeamProject { get; set; }

        public ObservableCollection<string> UserNames;
        
        public string SelectedUserName { get; set; }

        [XmlElement("TFSUri")]
        public string TFSUriString
        {
            get { return TFSUri.ToString(); }
            set { TFSUri = new Uri(value); }
        }

        public Uri GetTFSTeamProjectCollectionUri()
        {
            return (new Uri(this.TFSUriString + "\\" + this.ProjectCollection));
        }
    }

    public class MergeApproach
    {
        public string Name { get; set; }
        public ObservableCollection<BranchPair> BranchPairs { get; set; }
    }

    public class BranchPair
    {
        public int Order { get; set; }
        public string BranchNameFrom { get; set; }

        public string BranchNameTo { get; set; }

        public string CheckinCommentPattern { get; set; }

        public int ChangesetIdToStartFrom { get; set; }

        [XmlIgnore]
        public MergeOptionsEx MergeOption { get; set; }

        [XmlElement("MergeOption")]
        public string MergeOptionString
        {
            get { return MergeOption.ToString(); }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    MergeOption = MergeOptionsEx.None;
                }
                else
                {
                    try
                    {
                        MergeOption = (MergeOptionsEx)Enum.Parse(typeof(MergeOptionsEx), value); 
                    }
                    catch (ArgumentException argumentException)
                    {
                        throw new ArgumentException(string.Format("MergeOptionsEx allows only these values: {0}!", string.Join(",", Enum.GetNames(typeof(MergeOptionsEx)))));
                    }
                }
            }
        }
    }

}
